Skip to content

Feat/integration feature files repo#20

Open
marcocello wants to merge 15 commits intodebuglebowski:mainfrom
marcocello:feat/integration-feature-files-repo
Open

Feat/integration feature files repo#20
marcocello wants to merge 15 commits intodebuglebowski:mainfrom
marcocello:feat/integration-feature-files-repo

Conversation

@marcocello
Copy link
Copy Markdown

@marcocello marcocello commented Mar 2, 2026

Summary

This PR adds a feature-first workflow for tasks.

Now, a task can be linked to a project’s FEATURE.md, and that link is managed in a new Feature tab inside the task view.

The main goal is simple: keep tasks and feature docs in sync, so work stays aligned with what is written in the repository.

Objective

  • Link tasks to FEATURE.md
  • Keep task details and feature docs synchronized
  • Let users manage this directly from a Feature tab

What Changed

  1. Task and feature docs are connected
  • Tasks can now be tied to feature docs in the repo
  • Updates can flow between the task and FEATURE.md
  • Better handling when paths/files are missing
  1. New Feature tab in the task UI
  • Added a dedicated Feature tab
  • Users can create, edit, and sync feature-related content there
  • Improved acceptance criteria flow as part of this tab
  1. Stability improvements
  • Added safer migration/backfill behavior for older local databases
  • Added fallback behavior to avoid crashes on older setups

Why this matters

This makes feature documentation part of the daily task workflow, instead of something separate. It gives teams one clearer, more consistent way to plan and execute work.

Greptile Summary

This PR introduces a comprehensive feature-first workflow that bidirectionally syncs tasks with FEATURE.md files in the repository. Tasks can now be linked to feature documents, with updates flowing both ways to keep implementation aligned with documentation.

Key Changes

  • New sync engine (repo-feature-sync.ts, 1368 lines): Scans repository for FEATURE.md files, parses YAML/Markdown frontmatter, creates/updates tasks automatically, and writes task changes back to files
  • Feature tab in task UI: New dedicated tab (Cmd+F) for creating, editing, and viewing linked feature docs with auto-save and acceptance file browsing
  • Database schema: New project_feature_task_links table tracks bidirectional sync with content hashing and source tracking
  • Terminal behavior change: For codex mode with feature integration enabled, terminal CWD switches to feature directory instead of project root
  • Project settings: Toggle feature integration per-project with configurable features folder path and sync interval
  • Deletion flow: Optional checkbox to delete feature directory when deleting linked tasks

Strengths

  • Robust path validation: Extensive checks prevent path traversal attacks and enforce feature folders stay within repo boundaries
  • Schema safety: ensureSchemaBackfills auto-heals schema drift from external version bumps
  • Comprehensive testing: Test coverage for sync flows, path validation, and edge cases
  • Race condition handling: Proper request ID tracking in auto-save prevents stale writes

Performance Considerations

  • Sync on every read: Feature sync runs before every task query (getTasks, getTask, etc), which scans filesystem and parses all FEATURE.md files. With many features, this could add latency to task operations
  • 30-second polling: Background poller rescans all projects every 30 seconds (configurable 5-3600s)

Notable Behaviors

  • Moving a task to different project detaches feature link but leaves directory on disk (likely intentional to preserve work)
  • Terminal CWD changes to feature directory for codex mode - significant workflow change
  • Foreign key removed from terminal_tabs.task_id to support non-persisted repo-based tasks

Confidence Score: 4/5

  • This PR is generally safe to merge with minor performance considerations
  • Well-tested feature with robust security validation and comprehensive test coverage. Main concern is sync-on-read performance impact with large repos. No critical bugs found, but behavioral changes (terminal CWD, sync frequency) should be monitored in production.
  • packages/domains/task/src/main/handlers.ts for sync performance optimization

Important Files Changed

Filename Overview
packages/domains/projects/src/main/repo-feature-sync.ts New 1368-line module implementing bidirectional sync between tasks and FEATURE.md files with robust path validation and YAML/Markdown parsing
packages/domains/task/src/client/FeaturePanel.tsx New 441-line React component for feature tab UI with auto-save debouncing and acceptance file browsing
packages/apps/app/src/main/db/migrations.ts Adds feature linking schema with project_feature_task_links table, removes terminal_tabs FK, includes safety backfills for version drift
packages/domains/task/src/main/handlers.ts Integrates feature sync into task CRUD operations, syncs on every read which may impact performance with many features
packages/domains/projects/src/main/handlers.ts Adds feature integration settings with path validation, triggers sync on project create/update, detaches links when integration disabled
packages/domains/task/src/client/TaskDetailPage.tsx Adds Feature tab with Cmd+F shortcut, changes terminal CWD to feature directory for codex mode when integration enabled
packages/apps/app/src/main/index.ts Adds 30-second polling for feature repo sync, removes AI description handler, broadcasts tasks-changed event on sync

Sequence Diagram

sequenceDiagram
    participant User
    participant UI as FeaturePanel / TaskDetailPage
    participant IPC as Electron IPC
    participant Handler as Task/Project Handlers
    participant Sync as repo-feature-sync.ts
    participant FS as File System
    participant DB as SQLite Database

    Note over User,DB: Feature Creation Flow
    User->>UI: Click "Create FEATURE.md"
    UI->>IPC: createTaskFeature(taskId, input)
    IPC->>Handler: db:tasks:createFeature
    Handler->>Sync: createFeatureForTask(db, taskId)
    Sync->>DB: Check existing link
    Sync->>FS: Create feature dir & FEATURE.md
    Sync->>DB: INSERT project_feature_task_links
    Sync->>DB: UPDATE tasks SET title
    Sync-->>Handler: {created: true, featureFilePath}
    Handler-->>UI: {task, details}
    UI->>UI: Display feature editor

    Note over User,DB: Bidirectional Sync: User Edits Feature File
    User->>UI: Edit FEATURE.md content
    UI->>UI: Debounce 350ms
    UI->>IPC: fs.writeFile(projectPath, featureFilePath, content)
    IPC->>FS: Write file
    UI->>IPC: syncTaskFeatureFromRepo(taskId)
    IPC->>Handler: db:tasks:syncFeatureFromRepo
    Handler->>Sync: syncProjectFeatureTasks(db, projectId)
    Sync->>FS: Scan & parse FEATURE.md files
    Sync->>Sync: Calculate content hash
    Sync->>DB: UPDATE tasks SET title, description
    Sync->>DB: UPDATE project_feature_task_links
    Sync-->>Handler: {updated: true, sync}
    Handler-->>UI: {task, details}

    Note over User,DB: Bidirectional Sync: User Updates Task
    User->>UI: Update task title/description
    UI->>IPC: updateTask({id, title, description})
    IPC->>Handler: db:tasks:update
    Handler->>DB: UPDATE tasks
    Handler->>Sync: syncTaskToFeatureFile(db, taskId)
    Sync->>DB: SELECT feature_file_path from links
    Sync->>FS: Read existing FEATURE.md
    Sync->>Sync: Upsert frontmatter (id, title, description)
    Sync->>FS: Write updated FEATURE.md
    Sync->>DB: UPDATE project_feature_task_links (content_hash, last_sync_source='task')
    Sync-->>Handler: {updated: true}
    Handler-->>UI: updated task

    Note over User,DB: Background Polling (30s interval)
    loop Every 30 seconds
        Handler->>Sync: syncAllProjectFeatureTasks(db)
        Sync->>DB: SELECT projects WHERE feature_repo_integration_enabled=1
        loop For each project
            Sync->>FS: Scan repo for FEATURE.md files
            Sync->>Sync: Parse frontmatter & calculate hash
            Sync->>DB: Check existing links by content_hash
            alt Feature file changed
                Sync->>DB: UPDATE tasks (title, description)
                Sync->>DB: UPDATE project_feature_task_links
            end
            alt New FEATURE.md found
                Sync->>DB: INSERT tasks
                Sync->>DB: INSERT project_feature_task_links
            end
        end
        Sync-->>Handler: {created, updated, errors}
        Handler->>IPC: Broadcast tasks:changed event
    end

    Note over User,DB: Task Deletion with Feature Dir
    User->>UI: Delete task (checkbox: delete feature dir)
    UI->>IPC: deleteTask(taskId, {deleteFeatureDir: true})
    IPC->>Handler: db:tasks:delete
    Handler->>Sync: deleteFeatureForTask(db, taskId)
    Sync->>DB: SELECT feature_file_path from links
    Sync->>FS: rmSync(featureDirAbs, {recursive: true, force: true})
    Sync->>DB: DELETE FROM project_feature_task_links
    Sync-->>Handler: {deleted: true}
    Handler->>DB: UPDATE tasks SET deleted_at
    Handler-->>UI: success
Loading

Last reviewed commit: 39c0ff0

- Introduced new functions for task feature operations including create, delete, update, and sync from/to repository.
- Refactored cleanupTask function to utilize a dedicated cleanupTaskFromData function for better readability and error handling.
- Added IPC handlers for managing task features, including syncing and retrieving feature details.
- Updated task-related types to include feature management capabilities.
- Improved terminal component styling and behavior, ensuring a consistent dark theme.
- Removed unused AI description generation code and related types.
- Updated all references from feature.yaml to FEATURE.md in UserSettingsDialog, FeaturePanel, and TaskDetailPage components.
- Adjusted related test cases to reflect the new file naming convention.
- Modified database handlers to accommodate the change in feature file naming.
- Ensured that the application correctly handles the new FEATURE.md format in task-related functionalities.
…ing options in CodeEditor, remove MarkdownPreview, and implement acceptance file handling in FeaturePanel
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

44 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 3, 2026

Additional Comments (1)

packages/domains/file-editor/src/client/Screenshot 2026-03-02 at 16.35.31.png
screenshot file accidentally committed - not referenced anywhere in code

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/domains/file-editor/src/client/Screenshot 2026-03-02 at 16.35.31.png
Line: 1

Comment:
screenshot file accidentally committed - not referenced anywhere in code

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +387 to +392
const syncProjectRepoFeaturesSafe = (projectId: string | null | undefined): void => {
if (!projectId) return
try {
syncProjectFeatureTasks(db, projectId)
} catch (err) {
console.error(`Failed syncing PRD/spec tasks for project ${projectId}:`, err)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syncing on every task read could impact performance with large repos

syncProjectRepoFeaturesSafe scans the filesystem and parses all FEATURE.md files in the project. Called before every getTasks, getTasksByProject, getTask, and getSubTasks operation. With dozens of features, this adds latency to every task read.

Consider:

  • caching sync results with TTL
  • only syncing on explicit user action or poller interval
  • lazy-loading feature metadata on-demand
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/domains/task/src/main/handlers.ts
Line: 387-392

Comment:
syncing on every task read could impact performance with large repos

`syncProjectRepoFeaturesSafe` scans the filesystem and parses all FEATURE.md files in the project. Called before every `getTasks`, `getTasksByProject`, `getTask`, and `getSubTasks` operation. With dozens of features, this adds latency to every task read.

Consider:
- caching sync results with TTL
- only syncing on explicit user action or poller interval
- lazy-loading feature metadata on-demand

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +584 to +586
if (projectChanged) {
db.prepare('DELETE FROM project_feature_task_links WHERE task_id = ?').run(data.id)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moving a task to a different project leaves feature directory orphaned on disk

When projectChanged is true, the link is deleted from the database but deleteFeatureForTask is not called, so the feature directory remains in the old project's repo. Consider whether this is intentional (preserving work) or if cleanup should happen.

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/domains/task/src/main/handlers.ts
Line: 584-586

Comment:
moving a task to a different project leaves feature directory orphaned on disk

When `projectChanged` is true, the link is deleted from the database but `deleteFeatureForTask` is not called, so the feature directory remains in the old project's repo. Consider whether this is intentional (preserving work) or if cleanup should happen.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +807 to 811
markSkipCache(mainSessionId)
setTerminalKey((k) => k + 1)
}, [task, getMainSessionId, resetTaskState])

// Inject task description into terminal (no execute)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

terminal CWD switches to feature directory for codex mode - significant behavioral change

When codex mode is active and feature integration is enabled, the terminal's working directory changes from worktree/project path to the feature directory. This is a notable behavior change that affects where commands run. Consider documenting this or adding a visual indicator in the UI.

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/domains/task/src/client/TaskDetailPage.tsx
Line: 807-811

Comment:
terminal CWD switches to feature directory for codex mode - significant behavioral change

When codex mode is active and feature integration is enabled, the terminal's working directory changes from worktree/project path to the feature directory. This is a notable behavior change that affects where commands run. Consider documenting this or adding a visual indicator in the UI.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +1349 to +1350
}
fs.rmSync(featureDirAbs, { recursive: true, force: true })
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uses force: true which suppresses errors if directory doesn't exist

fs.rmSync with force: true silently succeeds even if the directory doesn't exist. This is likely intentional for idempotency, but consider logging when the directory wasn't found for debugging.

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/domains/projects/src/main/repo-feature-sync.ts
Line: 1349-1350

Comment:
uses `force: true` which suppresses errors if directory doesn't exist

`fs.rmSync` with `force: true` silently succeeds even if the directory doesn't exist. This is likely intentional for idempotency, but consider logging when the directory wasn't found for debugging.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants